home *** CD-ROM | disk | FTP | other *** search
- /*
- * tree.c - Creates a tree using Aono & Kunii's generation method.
- * (See IEEE CG&A May 1984). A square polygon is placed beneath the
- * tree to act as a field. No tree branch is clipped. Seven light sources.
- *
- * Version: 2.2 (11/17/87)
- * Author: Eric Haines, 3D/Eye, Inc.
- *
- * SIZE_FACTOR determines the number of objects output.
- * Total objects = 2**(SF+1)-1 cones and spheres + 1 square polygon.
- *
- * SIZE_FACTOR # spheres # cones # squares
- * 1 3 3 1
- * 2 7 7 1
- * 3 15 15 1
- *
- * 11 4095 4095 1
- */
-
- #include <stdio.h>
- #include <math.h>
- #include "def.h"
- #include "lib.h"
-
- #define OUTPUT_FORMAT OUTPUT_CURVES
- #define SIZE_FACTOR 9
-
- /* the following affect the shape of the tree */
- #define BR_ANGLE_0 40.0
- #define BR_ANGLE_1 25.0
- #define BR_CONTR_0 0.65
- #define BR_CONTR_1 0.70
- #define BR_DIAMETER 0.67
- #define DIV_ANGLE 140.0
- #define WIDTH_HEIGHTH_RATIO 0.15
-
-
- static MATRIX rst_mx[2] ;
-
- /* grow tree branches recursively */
- static void
- grow_tree(MATRIX cur_mx, double scale, long depth, char *txname)
- {
- COORD4 apex, base, vec ;
- long i ;
- MATRIX new_mx ;
-
-
- /* output branch */
- SET_COORD4( vec, 0.0, 0.0, 0.0, 1.0 ) ;
- lib_transform_coord( &base, &vec, cur_mx ) ;
- base.w = scale * WIDTH_HEIGHTH_RATIO ;
-
- SET_COORD4( vec, 0.0, 0.0, 1.0, 1.0 ) ;
- lib_transform_coord( &apex, &vec, cur_mx ) ;
- apex.w = base.w * BR_DIAMETER ;
-
- lib_output_cylcone( &base, &apex, txname ) ;
- lib_output_sphere( &apex, txname ) ;
-
- if ( depth > 0 ) {
- --depth ;
-
- for ( i = 0; i < 2; ++i ) {
- lib_matrix_multiply( new_mx, rst_mx[i], cur_mx ) ;
- grow_tree(new_mx, scale * BR_DIAMETER, depth, txname);
- }
- }
- }
-
- /*
- * Set up matrices for growth of each branch with respect to the
- * parent branch, then grow each branch.
- */
- static void
- create_tree(char *txname)
- {
- double branch_angle, branch_contraction, divergence ;
- long i ;
- MATRIX ident_mx, temp1_mx, temp2_mx, tempr_mx, tempst_mx ;
-
-
- for ( i = 0 ; i < 2 ; ++i ) {
- if ( i == 0 ) {
- branch_angle = BR_ANGLE_0 ;
- divergence = 90.0 ;
- branch_contraction = BR_CONTR_0 ;
- }
- else {
- branch_angle = BR_ANGLE_1 ;
- divergence = DIV_ANGLE + 90.0 ;
- branch_contraction = BR_CONTR_1 ;
- }
-
- /* rotate along X axis by branching angle */
- lib_create_rotate_matrix( temp1_mx, X_AXIS, branch_angle*PI/180.0 ) ;
-
- /* rotate along Z axis by divergence angle */
- lib_create_rotate_matrix( temp2_mx, Z_AXIS, divergence*PI/180.0 ) ;
-
- lib_matrix_multiply( tempr_mx, temp1_mx, temp2_mx ) ;
-
- /* include translation of branch, scaled */
- lib_create_identity_matrix( tempst_mx ) ;
- tempst_mx[0][0] = tempst_mx[1][1] = tempst_mx[2][2] =
- branch_contraction ;
- tempst_mx[3][2] = 1.0 ;
-
- /* concatenate */
- lib_matrix_multiply( rst_mx[i], tempr_mx, tempst_mx ) ;
- }
-
- /* set up initial matrix */
- lib_create_identity_matrix(ident_mx);
- grow_tree(ident_mx, 1.0, SIZE_FACTOR, txname);
- }
-
- void
- main(int argc, char *argv[])
- {
- COORD4 field[4] ;
- COORD4 from, at, up, dir;
- COORD4 light ;
- COORD4 back_color, tree_color ;
- char *txname;
-
- /* output viewpoint */
- SET_COORD( from, 4.5, 0.4, 2.0 ) ;
- SET_COORD( at, 0.0, 0.0, 1.5 ) ;
- SET_COORD( up, 0.0, 0.0, 1.0 ) ;
- lib_output_viewpoint( &from, &at, &up, 45.0, 1.0, 1.0, 256, 256);
-
- /* output background color - UNC sky blue */
- SET_COORD( back_color, 0.078, 0.361, 0.753 ) ;
- lib_output_background_color( &back_color ) ;
-
- /* output light sources */
- /*
- SET_COORD( light, -5.0, 5.0, 50.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, 30.0, -30.0, 30.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, -40.0, -30.0, 20.0 ) ;
- lib_output_light( &light ) ;
- */
- SET_COORD( light, 10.0, 30.0, 40.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, -30.0, 40.0, 10.0 ) ;
- lib_output_light( &light ) ;
- SET_COORD( light, 50.0, 25.0, 20.0 ) ;
- lib_output_light( &light ) ;
- /*
- SET_COORD( light, -10.0, -60.0, 30.0 ) ;
- lib_output_light( &light ) ;
- */
-
- /* Output bounding slabs oriented along the coordinate axes */
- SET_COORD(dir, 1.0, 0.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 1.0, 0.0);
- lib_output_bounding_slab(&dir);
- SET_COORD(dir, 0.0, 0.0, 1.0);
- lib_output_bounding_slab(&dir);
-
- /* output field polygon - green */
- SET_COORD( back_color, 0.2, 0.7, 0.2 ) ;
- txname = lib_output_color(&back_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0) ;
- SET_COORD( field[0], 50.0, 50.0, 0.0 ) ;
- SET_COORD( field[1], -50.0, 50.0, 0.0 ) ;
- SET_COORD( field[2], -50.0, -50.0, 0.0 ) ;
- SET_COORD( field[3], 50.0, -50.0, 0.0 ) ;
- lib_output_polygon(4, field, txname);
-
- /* set up tree color - brown */
- SET_COORD( tree_color, 0.55, 0.4, 0.2 ) ;
- txname = lib_output_color( &tree_color, 0.2, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0);
-
- /* create tree */
- create_tree(txname);
- }
-